package com.celesea.configuration.log;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public abstract class ExcludableFilter implements Filter {

	public static final String PARAM_NAME_EXCLUSIONS = "exclusions";

    protected Set<String> excludesPattern;
    protected FilterConfig config = null;

    public ExcludableFilter() {
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        this.config = filterConfig;
        String exclusions = filterConfig.getInitParameter(PARAM_NAME_EXCLUSIONS);
        if (exclusions != null && exclusions.trim().length() != 0) {
            excludesPattern = new HashSet<>(Arrays.asList(exclusions.split("\\s*,\\s*")));
        }
    }

    @Override
    public void doFilter(
            ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        if (isExclusion(req.getRequestURI())) {
            chain.doFilter(request, response);
            return;
        } else {
            doInternalFilter(request, response, chain);
        }
    }
    
    /**
     *
     * @param uri
     * @return
     */
    protected boolean isExclusion(String uri){
    	if (uri.indexOf("/themes/") > 0 || uri.indexOf("/js/") > 0 || uri.indexOf("/normal/") > 0) {
			return true;
		}
    	
    	if(excludesPattern != null && excludesPattern.size() > 0){
    		Iterator<String> iters = excludesPattern.iterator();
    		while(iters.hasNext()){
    			if(uri.indexOf(iters.next()) > 0){
    				return true;
    			}
    		}
    	}
    	
    	return false;
    }

    protected abstract void doInternalFilter(ServletRequest request, ServletResponse response, FilterChain chain)
		throws IOException, ServletException;

    @Override
    public void destroy() {

    }
}
